package com.tanhua.server.service;

import cn.hutool.core.collection.CollUtil;
import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.tanhua.autoconfig.templates.OssTemplate;
import com.tanhua.commons.utils.Constants;
import com.tanhua.dubbo.api.CommentApi;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.dubbo.api.VideoApi;
import com.tanhua.dubbo.api.VideoGuanzhuApi;
import com.tanhua.model.db.UserInfo;
import com.tanhua.model.mongo.Comment;
import com.tanhua.model.mongo.Video;
import com.tanhua.model.mongo.VideoGuanzhu;
import com.tanhua.model.vo.PageResult;
import com.tanhua.model.vo.VideoVo;
import com.tanhua.server.interceptor.UserHolder;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;


@Service
public class SmallVideosService {
    @Autowired
    private OssTemplate ossTemplate;

    @Autowired
    private FastFileStorageClient client;

    @Autowired
    private FdfsWebServer webServer;

    @DubboReference
    private VideoApi videoApi;
    @DubboReference
    private CommentApi commentApi;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @DubboReference
    private UserInfoApi userInfoApi;
    @DubboReference
    private VideoGuanzhuApi videoGuanzhuApi;

    @Autowired
    private MqMessageService mqMessageService;

    //视频上传
    public void saveVideo(MultipartFile videoThumbnail, MultipartFile videoFile) throws Exception {
        //1. 封面图牌能上传到阿里云oss
        String picUrl = ossTemplate.upload(videoThumbnail.getInputStream(), videoThumbnail.getOriginalFilename());
        //2. 视频上传到fastdfs
        String filename = videoFile.getOriginalFilename();
        int index = filename.lastIndexOf(".");
        filename = filename.substring(index + 1);
        StorePath storePath = client.uploadFile(videoFile.getInputStream(), videoFile.getSize(), filename, null);
        //拼接URL
        String videoUrl = webServer.getWebServerUrl() + storePath.getFullPath();
        //3. 构造video对象
        Video video = new Video();
        video.setCreated(System.currentTimeMillis());
        video.setText("我就是我，我是你爹");
        video.setUserId(UserHolder.getUserId());
        video.setPicUrl(picUrl);
        video.setVideoUrl(videoUrl);
        //4. 调用api保存
        videoApi.save(video);
    }

    //分页查询小视频
    public PageResult findVideos(Integer page, Integer pagesize) {
        //1. 在Redis中获取推荐视频
        String key = Constants.VIDEOS_RECOMMEND + UserHolder.getUserId();
        String value = redisTemplate.opsForValue().get(key);
        //2. 判断是否存在
        List<Video> videos = new ArrayList<>();
        if (StringUtils.isNotEmpty(value)) {
            //2.1 存在
            String[] ids = value.split(",");
            videos = videoApi.findByIds(ids, page, pagesize);
        } else {
            //2.2 不存在,查询所有视频
            videos = videoApi.findAll(page, pagesize);
        }
        if (CollUtil.isEmpty(videos)) {
            return new PageResult();
        }
        //3. 一次性获取所有发布人的信息
        List<Long> list = CollUtil.getFieldValues(videos, "userId", Long.class);
        Map<Long, UserInfo> map = userInfoApi.findByIds(list);
        //4. 将一个video转换成videoVo对象
        List<VideoVo> vos = new ArrayList<>();
        for (Video video : videos) {
            Long userId = video.getUserId();
            UserInfo userInfo = map.get(userId);
            VideoVo vo = VideoVo.init(userInfo, video);
            String redisKey = Constants.VIDEO_INTERACT_KEY + vo.getId();
            String hashKey = Constants.VIDEO_LIKE_HASHKEY + UserHolder.getUserId();
            Boolean hasKey = redisTemplate.opsForHash().hasKey(redisKey, hashKey);
            if (hasKey) {
                vo.setHasLiked(1);
            }
            String redisKey1 = Constants.FOCUS_USER_KEY + vo.getId();
            String hashKey1 = Constants.FOCUS_USER_HASHKEY + UserHolder.getUserId();
            Boolean hasKey1 = redisTemplate.opsForHash().hasKey(redisKey1, hashKey1);
            if (hasKey1) {
                vo.setHasFocus(1);
            }
            vos.add(vo);
        }
        return new PageResult(page, pagesize, 0l, vos);
    }

    //视频点赞
    public Integer like(String id) {
        Integer commentType = 1;
        //1. 调用api保存互动数据，更新动态表
        Long userId = UserHolder.getUserId();
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(id));
        comment.setUserId(userId);
        comment.setCommentType(commentType);
        comment.setCreated(System.currentTimeMillis());
        Integer count = commentApi.saveVideo(comment);
        //2. 将点赞状态，存入Redis（为了方便查询点赞状态）
        String redisKey = Constants.VIDEO_INTERACT_KEY + id;
        String hashKey = Constants.VIDEO_LIKE_HASHKEY + UserHolder.getUserId();
        redisTemplate.opsForHash().put(redisKey, hashKey, "1");
        mqMessageService.sendLogMessage(userId, "0302", "log.video", id);
        return count;
    }

    //取消点赞
    public Integer dislike(String id) {
        Integer commentType = 1;
        Long userId = UserHolder.getUserId();
        //1. 调用api删除互动数据，更新动态表
        Integer count = commentApi.deleteByvideo(commentType, userId, id);
        //2. 删除Redis中的数据
        String redisKey = Constants.VIDEO_INTERACT_KEY + id;
        String hashKey = Constants.VIDEO_LIKE_HASHKEY + userId;
        redisTemplate.opsForHash().delete(redisKey, hashKey);
        return count;


    }

    //发布评论
    public void saveComment(String comment, String id) {
        Integer commentType = 2;
        //1. 创建comment对象，设置属性值
        Comment comment1 = new Comment();
        comment1.setCommentType(commentType);
        comment1.setContent(comment);
        comment1.setPublishId(new ObjectId(id));
        comment1.setCreated(System.currentTimeMillis());
        comment1.setUserId(UserHolder.getUserId());
        Integer count = commentApi.saveVideo(comment1);
        System.out.println("评论总数" + count);

    }

    //关注
    public void userFocus(Long uid) {
        List<Video> videos = videoApi.findByUid(uid);
        VideoGuanzhu videoGuanzhu = new VideoGuanzhu();
        for (Video video : videos) {
            videoGuanzhu.setUserId(video.getUserId());
            videoGuanzhu.setCommentCount(video.getCommentCount());
            videoGuanzhu.setCreated(System.currentTimeMillis());
            videoGuanzhu.setLikeCount(video.getLikeCount());
            videoGuanzhu.setLoveCount(video.getLoveCount());
            videoGuanzhu.setPicUrl(video.getPicUrl());
            videoGuanzhu.setPublishUserId(UserHolder.getUserId());
            videoGuanzhu.setVideoUrl(video.getVideoUrl());
            videoGuanzhuApi.save(videoGuanzhu);
        }
        String redisKey = Constants.FOCUS_USER_KEY + uid;
        String hashKey = Constants.FOCUS_USER_HASHKEY + UserHolder.getUserId();
        redisTemplate.opsForHash().put(redisKey, hashKey, "1");

    }
    //取消关注
    public void userUnFocus(Long uid) {
        Long publishUserId = UserHolder.getUserId();
        videoGuanzhuApi.delete(uid,publishUserId);
        String redisKey = Constants.FOCUS_USER_KEY + uid;
        String hashKey = Constants.FOCUS_USER_HASHKEY + UserHolder.getUserId();
        redisTemplate.opsForHash().delete(redisKey,hashKey);

    }

}
